package com.ljb.android.comm.router

import android.app.Activity
import android.os.Bundle
import androidx.fragment.app.Fragment
import com.alibaba.android.arouter.launcher.ARouter
import com.google.gson.JsonObject
import com.ljb.android.comm.fragment.CommNotFoundFragment
import com.ljb.android.comm.router.service.*
import com.ljb.android.comm.rx.subscribeEx
import com.ljb.android.comm.utils.XLog
import com.ljb.android.component.user.router.IUserRouterService
import io.reactivex.rxjava3.core.Observable
import net.ljb.kt.utils.RxUtils
import java.util.concurrent.TimeUnit

object RouterManager {

    private val mSchemeHelper by lazy { SchemeHelper() }

    fun init() {
        getAppService()
        getUserService()
        getHomeService()
        getKnowService()
        getWXCodeService()
        getNavService()
        getProjectService()
        getSearchService()
    }

    /**
     * 获得Fragment
     * */
    fun getFragment(path: String): Fragment {
        val navigation = ARouter.getInstance().build(path)
            .navigation()
        var fragment: Fragment = CommNotFoundFragment()
        if (navigation != null && navigation is Fragment) {
            fragment = navigation
        }
        return fragment
    }

    /**
     * 跳转 WebView
     * */
    fun goWeb(url: String, title: String = "") {
        goActivity(
            RouterConfig.Activity.COMM_WEB,
            Bundle().apply {
                putString("url", url)
                putString("title", title)
            })
    }

    /**
     * 跳转 Activity
     * */
    fun goActivity(path: String, bundle: Bundle? = null) {
        ARouter.getInstance().build(path)
            .with(bundle)
            .navigation()
    }

    /**
     * 跳转 ActivityForResult
     * */
    fun goActivityForResult(
        path: String,
        bundle: Bundle? = null,
        activity: Activity,
        requestCode: Int
    ) {
        ARouter.getInstance().build(path)
            .with(bundle)
            .navigation(activity, requestCode)
    }


    fun getService(path: String): Any {
        return ARouter.getInstance().build(path).navigation()
    }


    /**
     * 通过 Service的字节码 获取 Service
     * */
    fun <T> getService(service: Class<out T>?): T? {
        return ARouter.getInstance().navigation(service)
    }


    /**
     * 获取User模块服务 - 用户信息
     */
    fun getUserService(): IUserRouterService? {
        return getService(IUserRouterService::class.java)
    }


    /**
     * 校验服务
     * */
    private fun <I : Class<*>> checkService(service: Any?, superClass: I): Boolean {
        if (service == null) {
            val msg = "not found service: ${superClass.simpleName}"
            XLog.e(msg)
            return false
        }

        if (!superClass.isAssignableFrom(service::class.java)) {
            val msg =
                "service found is error:  ${service::class.java.simpleName} not is ${superClass.simpleName}"
            XLog.e(msg)
            return false
        }
        return true
    }

    /**
     * 获取App模块服务
     */
    fun getAppService(): IAppRouterService? {
        val service = ARouter.getInstance().build(RouterConfig.Service.APP)
            .navigation()

        if (!checkService(service, IAppRouterService::class.java)) {
            return null
        }

        return service as IAppRouterService
    }

    /**
     * 获取Home模块服务 - 首页
     */
    fun getHomeService(): IHomeRouterService? {
        val service = ARouter.getInstance().build(RouterConfig.Service.HOME)
            .navigation()

        if (!checkService(service, IHomeRouterService::class.java)) {
            return null
        }

        return service as IHomeRouterService
    }

    /**
     * 获取Know模块服务 - 知识体系
     * */
    fun getKnowService(): IKnowRouterService? {

        val service = ARouter.getInstance().build(RouterConfig.Service.KNOW)
            .navigation()

        if (!checkService(service, IKnowRouterService::class.java)) {
            return null
        }

        return service as IKnowRouterService

    }

    /**
     * 获取WeChatCode模块服务 - 公众号
     * */
    fun getWXCodeService(): IWXCodeRouterService? {
        val service = ARouter.getInstance().build(RouterConfig.Service.WECHAT_CODE)
            .navigation()
        if (!checkService(service, IWXCodeRouterService::class.java)) {
            return null
        }
        return service as IWXCodeRouterService
    }

    /**
     * 获取Nav模块服务 - 导航
     * */
    fun getNavService(): INavRouterService? {
        val service = ARouter.getInstance().build(RouterConfig.Service.NAV)
            .navigation()

        if (!checkService(service, INavRouterService::class.java)) {
            return null
        }

        return service as INavRouterService
    }

    /**
     * 获取Project模块服务 - 项目
     * */
    fun getProjectService(): IProjectRouterService? {
        val service = ARouter.getInstance().build(RouterConfig.Service.PROJECT)
            .navigation()

        if (!checkService(service, IProjectRouterService::class.java)) {
            return null
        }

        return service as IProjectRouterService
    }

    /**
     * 获取Search模块服务 - 搜索
     * */
    fun getSearchService(): ISearchRouterService? {
        val service = ARouter.getInstance().build(RouterConfig.Service.SEARCH)
            .navigation()

        if (!checkService(service, ISearchRouterService::class.java)) {
            return null
        }

        return service as ISearchRouterService
    }


    /**
     * Scheme 路由跳转
     * */
    fun jumpUrl(jumpUrl: String?, delay: Long = 0L) {
        if (delay > 0L) {
            Observable.timer(delay, TimeUnit.MILLISECONDS)
                .compose(RxUtils.schedulerIO2Main())
                .subscribeEx {
                    onNextEx {
                        mSchemeHelper.jumpUrl(jumpUrl)
                    }
                }
        } else {
            mSchemeHelper.jumpUrl(jumpUrl)
        }
    }

    /**
     * 创建 Scheme 路由
     * */
    fun createUrl(action: RouterAction): String {
        return mSchemeHelper.createSchemeUrl(action)
    }

    // 测试生成 Scheme 路由
    fun testCreateUrl() {
        val action = RouterAction()
        action.action_type = RouterConfig.Scheme.ACTION_TYPE_CALL
        action.page_type = RouterConfig.Scheme.PAGE_TYPE_WEB
        action.path = RouterConfig.Activity.COMM_WEB
        val jsonObj = JsonObject()
        jsonObj.addProperty("title", "我是百度")
        jsonObj.addProperty("url", "https://www.baidu.com")
        action.params = jsonObj
        createUrl(action)
    }

}